import sys
from collections import defaultdict

user_key = defaultdict(list)
common_keys = {}

user_profile = False
item_ridx = False
user_key_word = False

num_items = 6095


def load_keyw(fname):
    for line in open(fname):
        if user_key_word:
            uid, keyw = line.strip().split()
            uid = int(uid)
            if uid >= num_items and item_feature:
                continue

            keyw = map(lambda s: s.split(':'), keyw.split(';'))
            keyw = map(lambda (fid, v): (int(fid), float(v)), keyw)
        elif user_profile:
            uid, birth, gender, retweet, keyw = line.strip().split()
            uid = int(uid)
            if uid >= num_items and item_feature:
                continue
            keyw = map(lambda s:(int(s), 1), keyw.split(';'))

        elif item_ridx:
            uid, cat, keyw = line.strip().split()
            uid = int(uid)
            if uid >= num_items and item_feature:
                continue
            keyw = map(lambda s:(int(s), 1), keyw.split(';'))
        
        user_key[uid] = keyw

def load_common_keys(fname):
    for line in open(fname):
        no, k, c = map(int, line.split())
        if no >= max_num_keys:
            break

        common_keys[k] = no

def process_keyw():
    for uid in user_key:
        keyw = user_key[uid]
        ckeyw = []
        tot_w = 0.0
        for k, w in keyw:
            if k in common_keys:
                ckeyw.append((common_keys[k], w))
                tot_w += w ** 2
        if ckeyw:
            tot_w = tot_w ** 0.5
            user_key[uid] = map(lambda (k, w): (k, w / tot_w), ckeyw)
        else:
            user_key[uid] = []

def print_features(ofile, features, offset = 0):
    if not features:
        ofile.write('0\n')
    else:
        for t in features:
            assert t[0] < len(common_keys)
        desc = map(lambda (fid, v): '%d:%.4f' % (fid + offset, v), features)
        ofile.write('%d %s\n' % (len(features), ' '.join(desc)))
        

if __name__ == '__main__':
    if len(sys.argv) < 7:
        print 'usage: <ukeyw> <common_keys> <max_num_keys> <offset> <out> <--item_feature| train.group>'
        print 'learn user_profile/user_key_word/item.ridx from filename'
        sys.exit(1)

    max_num_keys = int(sys.argv[3])

    offset = int(sys.argv[4])

    keywf = sys.argv[1]
    user_profile = keywf.find('user_profile') >= 0
    item_ridx = keywf.find('item') >= 0
    user_key_word = keywf.find('user_key_word') >= 0

    assert user_profile + item_ridx + user_key_word == 1

    item_feature = sys.argv[6] == '--item_feature'
    
    load_common_keys(sys.argv[2])
    print 'num_common_keys', len(common_keys)

    load_keyw(sys.argv[1])
    process_keyw()

    if sys.argv[6] == '--item_feature':
        print 'generating item features ...'
        itemf = open(sys.argv[5], "w")
        non_zero = 0
        for i in xrange(num_items):
            if user_key[i]:
                non_zero += 1
            print_features(itemf, user_key[i], offset)
        print 'nonzero items:', non_zero
        itemf.close()
        
    else:
        assert offset == 0
        print 'generating user implicit feedback ...'

        ukey_imfb = open(sys.argv[5], "w")
        ukey_imfb.write('%d\n' % len(common_keys))

        last_user = -1
        for line in open(sys.argv[6]):
            uid, iid, r, t = map(int, line.split())
            if last_user != uid:
                print_features(ukey_imfb, user_key[uid], offset)
            last_user = uid
        ukey_imfb.close()        
        
